﻿//JavaScript Document
var directionsService;
var _startPoint;
var _endPoint;
var startpointMarker;
var endpointMarker;
var startPointLatLng;
var endPointLatLng;
var myRoute;
var polyline;
var stepMarker;
var stepDetailArray = [];
var stepInfo = new google.maps.InfoWindow();

function startPoint(id, type, displayMarker) {
    this.id = id;
    this.type = type; // 0: point is searched from own db; 1: point is searched from google
    this.displayMarker = displayMarker;
    this.show = showStartPoint;
}

function endPoint(id, type, displayMarker) {
    this.id = id;
    this.type = type; // 0: point is searched from own db; 1: point is searched from google
    this.displayMarker = displayMarker;
    this.show = showEndPoint;
}

//move to point
function moveToPoint(lat, lng) {
    map.panTo(new google.maps.LatLng(lat, lng));
}

//show start point on the map
function showStartPoint() {
    if (this.type == 0)
        createStartPoint(this.id, this.displayMarker);
    else
        createGStartPoint(this.id, this.displayMarker);
}

//create start point that searched from own db
function createStartPoint(id, displayMarker) {
    $.getJSON("place/" + id, function (item) {
        var latlng = new google.maps.LatLng(item.latitude, item.longitude);

        if (displayMarker == true) {
            if (!startpointMarker) {
                startpointMarker = new google.maps.Marker({
                    map: map,
                    icon: 'images/start_point_1.png',
                    title: 'Chi tiết'
                });
            }
            startpointMarker.setPosition(latlng);
            google.maps.event.addListener(startpointMarker, 'click', function () {
                createInfoWindow(item.id);
            });
        } else {
            createInfoWindow(item.id);
            map.panTo(latlng);
        }

        //create info of start point bar in route box
        if ($("#start_address").length > 0) {
            var info = '<a onclick="moveToPoint(' + latlng.lat() + "," + latlng.lng() + ')">' + cutString($("#start_location").val()) + '</a>';
            $("#start_address").html(info);
        }
    });
 }

 //create start point that searched from google
 function createGStartPoint(id, displayMarker) {
     var service = new google.maps.places.PlacesService(map);
     var request = {
         reference: id
     }
     service.getDetails(request, function (place, getDetailStatus) {
         if (getDetailStatus == google.maps.places.PlacesServiceStatus.OK) {
             var latlng = place.geometry.location;

             if (displayMarker == true) {
                 if (!startpointMarker) {
                     startpointMarker = new google.maps.Marker({
                         map: map,
                         icon: 'images/start_point_1.png',
                         title: 'Chi tiết'
                     });
                 }
                 startpointMarker.setPosition(latlng);
                 google.maps.event.addListener(startpointMarker, 'click', function () {
                     if (!infowindow)
                         infowindow = new google.maps.InfoWindow();
                     else
                         infowindow.close();
                     infowindow.setContent(createGPlaceInfo(place));
                     infowindow.open(map, startpointMarker); // opening the InfoWindow  
                 });
             }
             else {
                 showGPlaceInfo(place);
                 map.panTo(latlng);
             }

             //create info of start point bar in route box
             if ($("#start_address").length > 0) {
                 var info = '<a onclick="moveToPoint(' + latlng.lat() + "," + latlng.lng() + ')">' + cutString($("#start_location").val()) + '</a>';
                 $("#start_address").html(info);
             }

         }
     });
 }

 //show end point on the map
 function showEndPoint() {
     if (this.type == 0)
         createEndPoint(this.id, this.displayMarker);
     else
         createGEndPoint(this.id, this.displayMarker);
 }

 //create end point that searched from own db
 function createEndPoint(id, displayMarker) {
     $.getJSON("place/" + id, function (item) {
         var latlng = new google.maps.LatLng(item.latitude, item.longitude);

         if (displayMarker == true) {
             if (!endpointMarker) {
                 endpointMarker = new google.maps.Marker({
                     map: map,
                     icon: 'images/end_point_1.png',
                     title: 'Chi tiết'
                 });
             }
             endpointMarker.setPosition(latlng);
             google.maps.event.addListener(endpointMarker, 'click', function () {
                 createInfoWindow(item.id);
             });
         }
         else {
             createInfoWindow(item.id);
             map.panTo(latlng);
         }
         //create info of end point bar in route box
         if ($("#end_address").length > 0) {
             var info = '<a onclick="moveToPoint(' + latlng.lat() + "," + latlng.lng() + ')">' + cutString($("#end_location").val()) + '</a>';
             $("#end_address").html(info);
         }
     });
 }

 //create end point that searched from google
 function createGEndPoint(id, displayMarker) {
     var service = new google.maps.places.PlacesService(map);
     var request = {
         reference: id
     }
     service.getDetails(request, function (place, getDetailStatus) {
         if (getDetailStatus == google.maps.places.PlacesServiceStatus.OK) {
             var latlng = place.geometry.location;

             if (displayMarker == true) {
                 if (!endpointMarker) {
                     endpointMarker = new google.maps.Marker({
                         map: map,
                         icon: 'images/end_point_1.png',
                         title: 'Chi tiết'
                     });
                 }
                 endpointMarker.setPosition(latlng);
                 google.maps.event.addListener(endpointMarker, 'click', function () {
                     if (!infowindow)
                         infowindow = new google.maps.InfoWindow();
                     else
                         infowindow.close();
                     infowindow.setContent(createGPlaceInfo(place));
                     infowindow.open(map, endpointMarker); // opening the InfoWindow  
                 });
             }
             else {
                 showGPlaceInfo(place);
                 map.panTo(latlng);
             }

             //create info of end point bar in route box
             if ($("#end_address").length > 0) {
                 var info = '<a onclick="moveToPoint(' + latlng.lat() + "," + latlng.lng() + ')">' + cutString($("#end_location").val()) + '</a>';
                 $("#end_address").html(info);
             }
         }
     });
 }

//create object that contain info of route
function route(start_address, end_address, duration, distance) {
    this.start_address = start_address;
    this.end_address = end_address;
    this.duration = duration;
    this.distance = distance; 
}

//create object that contain detail step of route
function stepDetail(instructions, distance, duration, start_location, end_location, start_point) {
    this.instructions = instructions;
	this.distance = distance;
	this.duration = duration;
	this.start_location = start_location;
	this.end_location = end_location;
	this.start_point = start_point;
	this.imgInst = getImgInstructions;
}

//remove some characters in intruction text of route (is returned by google) 
function replaceHtmlTagInText(text) {
    text = text.replace(/<b>|<\/b>|<\/div>/g, "");
    text = text.replace(/<div style="font-size:0.9em">/g, " ");
    return text;
}
 
//return image intruction
function getImgInstructions() {
    var inst = this.instructions;
    if (inst.indexOf("Đi về hướng") != -1)
        return "go_straight.png";
    if (inst.indexOf("Rẽ trái") != -1)
        return "turn_left.png";
    if (inst.indexOf("Rẽ phải") != -1)
        return "turn_right.png";
    if (inst.indexOf("Tại chỗ đường vòng") != -1)
        return "turn_back.png";
    return "go_straight.png";
}

//type 0: start point is searched from own db ; 1: start point is searched from google
function updateStartPoint(placeId, start_location, type) {
    changeTab('#tab2');

    $("#hasStartPoint").val("true");
    $("#placeIdStart").val(placeId);
    $("#start_location").val(start_location);
    if (type == 1)
        $("#isGStartPoint").val("true");

    if ($("#hasEndPoint").val() == "false")
        createQtip("#btnSearchRoute", "Nhấp đề tìm điểm đến !", 190, -50, 0); //show qtip
    else
        createQtip("#btnSearchRoute", "Nhấp để xem chi tiết đường đi !", 220, -50, 0);  //show qtip

    _startPoint = new startPoint(placeId, type, false);
    _startPoint.show();
}

//type 0: start point is searched from own db; 1: end point is searched from google
function updateEndPoint(placeId, end_location, type) {
    changeTab('#tab2');

    $("#hasEndPoint").val("true");
    $("#placeIdEnd").val(placeId);
    $("#end_location").val(end_location);
    if (type == 1)
        $("#isGEndPoint").val("true");

    if ($("#hasStartPoint").val() == "true")
        createQtip("#btnSearchRoute", "Nhấp để xem chi tiết đường đi !", 220, -50, 0); //show qtip
    else
        createQtip("#btnSearchRoute", "Nhấp đề tìm điểm đến !", 190, -50, 0);   //show qtip

    _endPoint = new endPoint(placeId, type, false);
    _endPoint.show();
}

//get latlng of place
function getStoreLatLng(placeId, callback) {
    var latlng;
    $.ajax({
        url: "place/" + placeId,
        async: false,
        dataType: 'json',
        success: function (item) {
            latlng = new google.maps.LatLng(item.latitude, item.longitude)
        }
    });
    callback(latlng);
}


//get latlng of gplace
function getGPlaceLatLng(reference, callback) {
    var service = new google.maps.places.PlacesService(map);
    var request = {
        reference: reference
    }
    service.getDetails(request, function (place, getDetailStatus) {
        if (getDetailStatus == google.maps.places.PlacesServiceStatus.OK) {
            callback(place.geometry.location);
        }
    });
}

//get detail route; type: WALKING|MOTORBIKE|DRIVING
function DetailofRoute(type) {    
    //if start point == end point then don't do anything
    if ($("#start_location").val() == $("#end_location").val()) {
        document.getElementById('draggable').style.visibility = "hidden";
        openFancybox();
        return;
    }
    
    //note: can not return variable in callback (ajax)
    //case 1:
    if ($("#isGStartPoint").val() == "false") {
        _startPoint = new startPoint($("#placeIdStart").val(), 0, true);
        getStoreLatLng($("#placeIdStart").val(), function (latlng) {
            startPointLatLng = latlng; //start point
        });

        if ($("#isGEndPoint").val() == "false") {
            _endPoint = new endPoint($("#placeIdEnd").val(), 0, true);
            getStoreLatLng($("#placeIdEnd").val(), function (latlng) {
                endPointLatLng = latlng; //end point
                calcRoute(startPointLatLng, endPointLatLng, type);
            });
        }
        else { //point is searched from google
            _endPoint = new endPoint($("#placeIdEnd").val(), 1, true);
            getGPlaceLatLng($("#placeIdEnd").val(), function (latlng) {
                endPointLatLng = latlng; //end point
                calcRoute(startPointLatLng, endPointLatLng, type);
            });
        }
    }

    //case 2:
    if ($("#isGStartPoint").val() == "true") { //point is searched from google
        _startPoint = new startPoint($("#placeIdStart").val(), 1, true);
        getGPlaceLatLng($("#placeIdStart").val(), function (latlng) {
            startPointLatLng = latlng; //start point
            
            if ($("#isGEndPoint").val() == "false") {
                _endPoint = new endPoint($("#placeIdEnd").val(), 0, true);
                getStoreLatLng($("#placeIdEnd").val(), function (latlng) {
                    endPointLatLng = latlng; //end point
                    calcRoute(startPointLatLng, endPointLatLng, type);
                });
            }
            else { //point is searched from google
                _endPoint = new endPoint($("#placeIdEnd").val(), 1, true);
                getGPlaceLatLng($("#placeIdEnd").val(), function (latlng) {
                    endPointLatLng = latlng; //end point
                    calcRoute(startPointLatLng, endPointLatLng, type);
                });
            }
        });
    }

    $("#routelistDiv").hide();
    $("#routelist").selectbox("detach"); //remove ui for combobox
}


//request route; type: DEFAULT|WALKING |DRIVING
function calcRoute(start, end, type) {
    //make request route
    var typeTem = type;
    if (type == "MOTORBIKE") {
        typeTem = "DRIVING";   
    }

    var requestRoute = {
        origin: start,
        destination: end,
        provideRouteAlternatives: true,
        travelMode: google.maps.TravelMode[typeTem]
    };

    _startPoint.show();
    _endPoint.show();

    //callback function
    directionsService.route(requestRoute, function (response, status) {
        if (status == google.maps.DirectionsStatus.OK) {
            //directionsDisplay.setDirections(response);
            var idMinRoute = getMinRoute(response.routes);

            //create option route
            var option = "";
            $('#routelist').html(" ");
            for (var i = 0; i < response.routes.length; i++) {
                if (i == idMinRoute)
                    option = '<option value="' + i + '"' + ' selected="selected"' + '>Đường đi ' + (i + 1) + ' * </option>';
                else
                    option = '<option value="' + i + '">Đường đi ' + (i + 1) + '</option>';
                $('#routelist').append(option);
            }

            $("#routelist").selectbox(); //attach ui for combobox
            $("#routelistDiv").show();

            //add event when user change route
            $('#routelist').bind('change keyup', function () {

                //get value of selected option
                var value = $(this).children("option:selected").attr('value');
                //clear step marker if it exsit
                if (stepMarker)
                    stepMarker.setMap(null);
                showSteps(response.routes[value], type);
                $("#routelist").selectbox("close");

            }).change();
        }
    });
}

//get route which has sortest distance
function getMinRoute(routes) {
    var idRoute = 0;
    var min = routes[0].legs[0].distance.value;
    for (var i = 0; i < routes.length; i++) { 
        var tem = routes[i].legs[0].distance.value; 
        if(tem < min){
            min = tem;
            idRoute = i;
        }
    }
    return idRoute;
}


//generate html for detail route
function showSteps(directionResult, type) {
    var typeText = "";
    if (type == "WALKING")
        typeText = "Đi bộ ";
    if (type == "MOTORBIKE") 
        typeText = "Đi xe máy ";
    if (type == "DRIVING")
        typeText = "Đi ô tô ";
    
    var innerHtml = "";
    stepDetailArray = [];

    drawRoute(directionResult.overview_path, directionResult.bounds);
    myRoute = directionResult.legs[0];
    var routeInfo = new route(myRoute.start_address, myRoute.end_address, myRoute.duration.text, myRoute.distance.text);
    for (var i = 0; i < myRoute.steps.length; i++) {
        var node = new stepDetail(replaceHtmlTagInText(myRoute.steps[i].instructions), myRoute.steps[i].distance, myRoute.steps[i].duration, myRoute.steps[i].start_location, myRoute.steps[i].end_location, myRoute.steps[i].start_point);
        stepDetailArray.push(node);
    }

    $("#listInts").html(" ");
    for (var i = 0; i < stepDetailArray.length; i++) {
        var tem = '<tr>'
                        	  + '<td style="background:url(../../images/' + stepDetailArray[i].imgInst() + ")" + " no-repeat center" + '"' + ' class="imgInstruction"></td>'
                              + '<td class="spnStreetName"><a onclick="showStepInfo(' + i +"," + stepDetailArray[i].start_point.lat() + "," + stepDetailArray[i].start_point.lng() + ')">' + (i+1) + '. ' + stepDetailArray[i].instructions + '</a></td>'
                          	  + '<td class="spnStreetName" style="white-space:nowrap" align="right">' + stepDetailArray[i].distance.value + ' m</td>'
                              + '</tr>';
        innerHtml += tem;
    }
    $("#listInts").html(innerHtml);
    $("#infoRoute").html(typeText + routeInfo.duration + " - " + routeInfo.distance);
    $("#mcs1_container").mCustomScrollbar("vertical", 0, "easeOutCirc", 1.05, "auto", "yes", "no", 0);
}

//draw route
function drawRoute(path, bounds) {
    // creating the polyline object
    if (!polyline) {
        polyline = new google.maps.Polyline({
            strokeColor: "#ff0000",
            strokeOpacity: 0.6,
            strokeWeight: 5
        });
    }
    polyline.setPath(path);

    // adding the polyline to the map 
    polyline.setMap(map);

    //bound the polyline
    map.fitBounds(bounds);
}

//show step info when user click on each step
function showStepInfo(i, lat, lng) {
    if (!stepMarker) {
        stepMarker = new google.maps.Marker({
            clickable: false
        });
    }
    stepMarker.setMap(map);
    stepMarker.setIcon('http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=' + (i + 1) + '|3399ff|ffffff'); //set icon for marker
    stepMarker.setPosition(new google.maps.LatLng(lat, lng));
    map.panTo(new google.maps.LatLng(lat, lng));
}